/*******************************
 *         硬件抽象层(HAL)
 ******************************/
// 增强型GPIO操作结构体
typedef struct {
    void (*set_output)(void);    // 设置为输出模式
    void (*set_input)(void);     // 设置为输入模式（可选）
    void (*set_high)(void);      // 输出高电平
    void (*set_low)(void);       // 输出低电平
    uint8_t (*read)(void);       // 输入读取（可选）
} GPIO_TypeDef;

// 错误码定义
typedef enum {
    LCD_OK           = 0,
    LCD_ERR_INIT     = -1,
    LCD_ERR_PARAM    = -2,
    LCD_ERR_TIMEOUT  = -3
} LCD_ErrorTypeDef;

// 延时函数指针类型
typedef void (*delay_func)(uint32_t duration);

// LCD配置结构体
typedef struct {
    // 控制线
    GPIO_TypeDef RS;
    GPIO_TypeDef RW;
    GPIO_TypeDef EN;
    
    // 数据线（支持4/8位模式）
    GPIO_TypeDef DATA[8];
    
    // 时序参数（单位：微秒）
    struct {
        uint16_t en_pulse;       // EN脉冲宽度
        uint16_t cmd_delay;      // 命令延迟
        uint16_t init_delay;     // 初始化延迟
    } timing;
    
    // 延时函数
    delay_func delay_ms;
    delay_func delay_us;
    
    // 工作模式
    uint8_t data_bits;          // 4 or 8
    uint8_t display_lines;      // 1 or 2
} LCD_ConfigTypeDef;

/*******************************
 *         应用层(APL)
 ******************************/
// 不透明句柄结构体
typedef struct {
    LCD_ConfigTypeDef config;
    uint8_t display_control;
    uint8_t entry_mode;
} LCD_HandleTypeDef;

// LCD命令定义
typedef enum {
    LCD_CMD_CLEAR        = 0x01,
    LCD_CMD_HOME         = 0x02,
    LCD_CMD_ENTRY_MODE   = 0x04,
    LCD_CMD_DISPLAY_CTRL = 0x08,
    LCD_CMD_SHIFT        = 0x10,
    LCD_CMD_FUNCTION_SET = 0x20,
    LCD_CMD_CGRAM_ADDR   = 0x40,
    LCD_CMD_DDRAM_ADDR   = 0x80
} LCD_CommandTypeDef;

// 创建LCD实例（带错误检查）
LCD_ErrorTypeDef LCD_Create(LCD_HandleTypeDef** hlcd, const LCD_ConfigTypeDef* config)
{
    if(!hlcd || !config) return LCD_ERR_PARAM;
    
    *hlcd = malloc(sizeof(LCD_HandleTypeDef));
    if(!*hlcd) return LCD_ERR_INIT;
    
    memcpy(&(*hlcd)->config, config, sizeof(LCD_ConfigTypeDef));
    (*hlcd)->display_control = 0;
    (*hlcd)->entry_mode = 0;
    return LCD_OK;
}

// 硬件初始化
static LCD_ErrorTypeDef hardware_init(LCD_HandleTypeDef* hlcd)
{
    // 配置控制线
    hlcd->config.RS.set_output();
    hlcd->config.RW.set_output();
    hlcd->config.EN.set_output();

    // 配置数据线
    for(int i=0; i < hlcd->config.data_bits; i++) {
        if(i >= 8) break;
        hlcd->config.DATA[i].set_output();
    }
    return LCD_OK;
}

// 安全写入函数（带超时检测）
static LCD_ErrorTypeDef lcd_write(LCD_HandleTypeDef* hlcd, uint8_t data, uint8_t rs_mode)
{
    // 参数校验
    if(!hlcd || !hlcd->delay_us) return LCD_ERR_PARAM;

    // 设置RS引脚
    rs_mode ? hlcd->config.RS.set_high() : hlcd->config.RS.set_low();
    
    // 设置RW为写模式
    hlcd->config.RW.set_low();

    // 8位模式传输
    if(hlcd->config.data_bits == 8) {
        for(int i=0; i<8; i++) {
            (data & (1<<i)) ? hlcd->config.DATA[i].set_high() 
                            : hlcd->config.DATA[i].set_low();
        }
    }
    // 4位模式传输
    else {
        // 高四位
        for(int i=4; i<8; i++) {
            (data & (1<<i)) ? hlcd->config.DATA[i-4].set_high()
                            : hlcd->config.DATA[i-4].set_low();
        }
        // 产生EN脉冲
        hlcd->config.EN.set_high();
        hlcd->delay_us(hlcd->config.timing.en_pulse);
        hlcd->config.EN.set_low();
        hlcd->delay_us(hlcd->config.timing.cmd_delay);

        // 低四位
        for(int i=0; i<4; i++) {
            (data & (1<<i)) ? hlcd->config.DATA[i].set_high()
                            : hlcd->config.DATA[i].set_low();
        }
    }

    // 产生EN脉冲
    hlcd->config.EN.set_high();
    hlcd->delay_us(hlcd->config.timing.en_pulse);
    hlcd->config.EN.set_low();
    hlcd->delay_us(hlcd->config.timing.cmd_delay);

    return LCD_OK;
}

// 增强初始化流程
LCD_ErrorTypeDef LCD_Init(LCD_HandleTypeDef* hlcd)
{
    if(!hlcd) return LCD_ERR_PARAM;

    hardware_init(hlcd);
    hlcd->delay_ms(50);

    // 初始化序列（兼容4/8位模式）
    uint8_t function_set = LCD_CMD_FUNCTION_SET;
    function_set |= (hlcd->config.data_bits == 8) ? 0x10 : 0x00;
    function_set |= (hlcd->config.display_lines > 1) ? 0x08 : 0x00;

    // 三次初始化尝试
    for(int i=0; i<3; i++) {
        lcd_write(hlcd, function_set | 0x30, 0);
        hlcd->delay_ms(5);
    }

    // 设置工作模式
    lcd_write(hlcd, function_set, 0);
    hlcd->delay_ms(1);

    // 显示控制
    hlcd->display_control = LCD_CMD_DISPLAY_CTRL | 0x04; // 默认关闭显示
    lcd_write(hlcd, hlcd->display_control, 0);

    // 清屏
    LCD_Clear(hlcd);

    // 进入模式设置
    hlcd->entry_mode = LCD_CMD_ENTRY_MODE | 0x02; // 默认增量模式
    lcd_write(hlcd, hlcd->entry_mode, 0);

    // 最后打开显示
    LCD_DisplayOn(hlcd);
    return LCD_OK;
}

// 增强API
LCD_ErrorTypeDef LCD_DisplayOn(LCD_HandleTypeDef* hlcd) {
    if(!hlcd) return LCD_ERR_PARAM;
    hlcd->display_control |= 0x04;
    return lcd_write(hlcd, hlcd->display_control, 0);
}

LCD_ErrorTypeDef LCD_CreateChar(LCD_HandleTypeDef* hlcd, uint8_t location, const uint8_t charmap[8]) {
    if(location >= 8) return LCD_ERR_PARAM;
    lcd_write(hlcd, LCD_CMD_CGRAM_ADDR | (location<<3), 0);
    for(int i=0; i<8; i++) {
        lcd_write(hlcd, charmap[i], 1);
    }
    return LCD_OK;
}

// 带格式的打印函数
LCD_ErrorTypeDef LCD_Printf(LCD_HandleTypeDef* hlcd, uint8_t row, uint8_t col, const char* format, ...) {
    char buffer[32];
    va_list args;
    va_start(args, format);
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    LCD_SetCursor(hlcd, row, col);
    return LCD_Print(hlcd, buffer);
}